import { _decorator, Node, Vec2, UITransform } from "cc";
import { EntityManager } from "../../Base/EntityManager";
import { EntityTypeEnum, InputTypeEnum, toFixed } from "../../Common";
import { EntityStateEnum, EventEnum } from "../../Enum";
import DataManager from "../../Global/DataManager";
import EventManager from "../../Global/EventManager";
import { WeaponStateMachine } from "./WeaponStateMachine";
const { ccclass } = _decorator;

@ccclass("WeaponManager")
export class WeaponManager extends EntityManager {
  owner: number;
  type: EntityTypeEnum;

  private body: Node;
  private anchor: Node;
  private point: Node;

  init({ id, weaponType }: { id: number; weaponType: EntityTypeEnum }) {
    this.owner = id;
    this.type = weaponType;

    this.node.setSiblingIndex(0);
    this.body = this.node.getChildByName("Body");
    this.anchor = this.body.getChildByName("Anchor");
    this.point = this.anchor.getChildByName("Point");

    this.fsm = this.body.addComponent(WeaponStateMachine);
    this.fsm.init(weaponType);
    this.state = EntityStateEnum.Idle;

    EventManager.Instance.on(EventEnum.WeaponShoot, this.handleWeaponShoot, this);
    EventManager.Instance.on(EventEnum.BulletBorn, this.handleBulletBorn, this);
  }

  onDestroy() {
    EventManager.Instance.off(EventEnum.WeaponShoot, this.handleWeaponShoot, this);
    EventManager.Instance.off(EventEnum.BulletBorn, this.handleBulletBorn, this);
  }

  handleBulletBorn(owner: number) {
    if (this.owner !== owner) {
      return;
    }

    this.state = EntityStateEnum.Attack;
  }

  handleWeaponShoot() {
    if (DataManager.Instance.myPlayerId !== this.owner) {
      return;
    }
    const pointWorldPos = this.point.getWorldPosition();
    const pointStagePos = DataManager.Instance.stage.getComponent(UITransform).convertToNodeSpaceAR(pointWorldPos);
    const anchorWorldPos = this.anchor.getWorldPosition();
    const directionVec2 = new Vec2(pointWorldPos.x - anchorWorldPos.x, pointWorldPos.y - anchorWorldPos.y).normalize();

    EventManager.Instance.emit(EventEnum.ClientSync, {
      type: InputTypeEnum.WeaponShoot,
      owner: this.owner,
      position: {
        x: toFixed(pointStagePos.x),
        y: toFixed(pointStagePos.y),
      },
      direction: {
        x: toFixed(directionVec2.x),
        y: toFixed(directionVec2.y),
      },
    });
  }
}
